package gipfProject.games.tzaar.gui;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;

import gipfProject.tools.ResourceLoader;

import javax.swing.JPanel;

import gipfProject.games.tzaar.data.PieceData;
import gipfProject.games.tzaar.data.TzaarData;
import gipfProject.games.tzaar.engine.TzaarEngine;

public class BoardUI extends JPanel implements MouseListener {

	ResourceLoader images;
	TzaarData gameState;
	TzaarEngine engine;
	TzaarUI gui;

	static final int colSize = 40, rowSize = 24, xOffset = 12, yOffset = 10, tileSize = 32;

	public BoardUI(ResourceLoader images, TzaarData gameState, TzaarEngine engine,
			TzaarUI gui) {
		this.images = images;
		this.gameState = gameState;
		this.engine = engine;
		this.gui = gui;
		addMouseListener(this);
	}

	public void paintComponent(Graphics g) {
		// Draw a border around the board
		g.setColor(Color.black);
		g.drawRect(0, 0, getSize().width - 1, getSize().height - 1);
		g.drawRect(1, 1, getSize().width - 3, getSize().height - 3);

		// Fill the center of the board
		g.setColor(TzaarColors.boardBackground);
		g.fillRect(2, 2, getSize().width - 4, getSize().height - 4);

		// Draw the background image
		//Image pieceImg = images.getResource("BoardArt");
		//g.drawImage(pieceImg, 0, 0, this);
		
		//Draw the grid on the board
		drawHexGrid(g);
		
		// For each tile on the board
		for (int col = 0; col < TzaarData.boardCols; col++) {
			for (int row = 0; row < TzaarData.boardRows; row++) {

				// Get the piece at that spot
				PieceData piece = gameState.getPiece(col,row);

				// If this is a valid piece, draw it
				if (piece.isValid()) {
					drawPiece(g, col, row, piece);
				}
			}
		}

	}// End of paint

	private void drawHexGrid(Graphics g){
		//Vertical
		drawHexLine(g,0,5,0,13);
		drawHexLine(g,1,4,1,14);
		drawHexLine(g,2,3,2,15);
		drawHexLine(g,3,2,3,16);
		
		drawHexLine(g,4,1,4,7);
		drawHexLine(g,4,11,4,17);
		
		drawHexLine(g,5,2,5,16);
		drawHexLine(g,6,3,6,15);
		drawHexLine(g,7,4,7,14);
		drawHexLine(g,8,5,8,13);
		
		//Top-Left -> Bottom-Right
		drawHexLine(g,4,1,8,5);
		drawHexLine(g,3,2,8,7);
		drawHexLine(g,2,3,8,9);
		drawHexLine(g,1,4,8,11);
		
		drawHexLine(g,0,5,3,8);
		drawHexLine(g,5,10,8,13);
		
		drawHexLine(g,0,7,7,14);
		drawHexLine(g,0,9,6,15);
		drawHexLine(g,0,11,5,16);
		drawHexLine(g,0,13,4,17);
		
		//Bottom-left to top-right
		drawHexLine(g,0,5,4,1);
		drawHexLine(g,0,7,5,2);
		drawHexLine(g,0,9,6,3);
		drawHexLine(g,0,11,7,4);
		
		drawHexLine(g,0,13,3,10);
		drawHexLine(g,5,8,8,5);
		
		drawHexLine(g,1,14,8,7);
		drawHexLine(g,2,15,8,9);
		drawHexLine(g,3,16,8,11);
		drawHexLine(g,4,17,8,13);
	}
	
	private void drawHexLine(Graphics g, int startCol,int startRow,int endCol,int endRow){
		// Set up our 2D graphics
		Graphics2D g2 = (Graphics2D) g;

		// Change the line-color to yellow
		g2.setColor(Color.black);

		// Change the line thickness to 3 pixels
		g2.setStroke(new BasicStroke(3));
		
		g2.drawLine(
				startCol * colSize + xOffset + (tileSize/2),
				startRow * rowSize + yOffset + (tileSize/2),
				endCol   * colSize + xOffset + (tileSize/2),
				endRow   * rowSize + yOffset + (tileSize/2)
		);
	}
	
	public void drawPiece(Graphics g, int col, int row, PieceData piece) {
		Image pieceImg = images.getResource(piece.imageFile());

		g.drawImage(pieceImg, xOffset + col * colSize, yOffset + row
				* rowSize, this);
	}// End drawPiece
	
	//TODO
	private void handleClick(int col, int row) {
		System.out.println(col + ":" + row);
	}

	public void mousePressed(MouseEvent e) {
		// Adjust the coordinates to match the board's grid
		int col = (e.getX() - xOffset) / colSize;
		int row = (e.getY() - yOffset - 15) / rowSize; // FIXME: Magic Number

		// If this is a skipped/offset tile, adjust to a real tile
		if (row % 2 == col % 2) {
			row++;
		}

		// If the result is within the bounds of the board, process the click
		if (col >= 0 && col < gameState.boardCols && row >= 0
				&& row < gameState.boardRows) {
			handleClick(col, row);
		}

		// "Consume" the event so it won't be processed in the
		// default manner by the source which generated it.
		e.consume();
	}// End mosePressed

	// These functions do not get used
	public void mouseClicked(MouseEvent e)  {}
	public void mouseEntered(MouseEvent e)  {}
	public void mouseExited(MouseEvent e)   {}
	public void mouseReleased(MouseEvent e) {}

}
